package lightswitch.server.code.sqlhelper.statement.insert;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lightswitch.server.code.object.DataRow;
import lightswitch.server.code.object.Database;
import lightswitch.server.code.object.MyEntry;
import lightswitch.server.code.sqlhelper.expression.NormalTable;
import lightswitch.server.code.sqlhelper.statement.Statement;
import lightswitch.server.code.util.StringHelper;
import lightswitch.server.code.util.TypeOfData;

public class Insert implements Statement {

	String tableName = "";
	List<String> columnList;
	// List<MyEntry> entryList;
	List<InsertItem> itemList;

	public Insert(String statement) {
		columnList = new ArrayList<>();
		// entryList = new ArrayList<>();
		itemList = new ArrayList<>();
		parse(statement);
	}

	@Override
	public void parse(String statement) {
		// TODO Auto-generated method stub

		String columnListString = "";
		String valuesString = "";

		statement = StringHelper.NormalizeString(statement);

		// Pattern p =
		// Pattern.compile("^(insert into([A-Za-z0-9 ^( ]+)[(]([,A-Za-z0-9 ^)]+)[)] values[(]([ ,A-Za-z0-9 ^)]+)[)])|(insert into( [A-Za-z0-9 ^(]+)values[(]([ ,A-Za-z0-9 ^)]+)[)])$");
		Pattern p = Pattern.compile("^(insert into (.+) values (.+))$");
		Matcher m = p.matcher(statement);
	
		if (m.find()) {
			if (m.group(1) != null) {
				tableName = m.group(2);
				valuesString = m.group(3);

			}

		}
		tableName = StringHelper.NormalizeString(tableName);
		if (tableName.contains("(") && tableName.contains(")")) {
			tableName = tableName.substring(0, tableName.length() - 1);
			String[] splStr = tableName.split("\\(");
			if (splStr.length == 2) {
				tableName = splStr[0];
				columnListString = splStr[1];

			} else {
				// throw exception
				return;
			}

		} else {
			columnListString = "";
		}
		tableName = StringHelper.NormalizeString(tableName);
		columnListString = StringHelper.NormalizeString(columnListString);
		if (!columnListString.equals("")) {
			String[] str = columnListString.split(",");
			for (int i = 0; i < str.length; i++) {
				str[i] = StringHelper.NormalizeString(str[i]);
				columnList.add(str[i]);
			}
		}


		valuesString = StringHelper.NormalizeString(valuesString);
		List<String> insertItemStatement = StringHelper
				.SplitStringInEqualLevelKeepingToken(valuesString);

		for (int i = 0; i < insertItemStatement.size(); i++) {
			itemList.add(new InsertItem(insertItemStatement.get(i),columnList));
		}

	}

	public int execute() {
		DataRow _row = null;
		NormalTable tb = new NormalTable(tableName);
		tb.InitTable();
		int count =0;

		for (InsertItem item : itemList) {
			
			if (tb.propertyList.size() < columnList.size()
					|| (columnList.size() != item.entryList.size() && columnList
							.size() > 0)
					|| (columnList.size() == 0 && item.entryList.size() != tb.propertyList
							.size())) {
				// throw exception
				return -1;
			}
			// kiem tra cac entry
			if (columnList.size() == 0) {
				_row = new DataRow();
				for (int i = 0; i < tb.propertyList.size(); i++) {
					MyEntry en = item.entryList.get(i);
					en.setName(tb.propertyList.get(i).getName());
					String type1 = "";
					String type2 = "";
					if (en.getDataType().equals(TypeOfData.FLOAT)
							|| en.getDataType().equals(TypeOfData.INT))
						type1 = TypeOfData.FLOAT;
					else {
						if (en.getDataType().equals(TypeOfData.BOOLEAN))
							type1 = TypeOfData.BOOLEAN;
						else
							type1 = TypeOfData.CHAR;
					}

					if (tb.propertyList.get(i).getTypeOfData()
							.equals(TypeOfData.FLOAT)
							|| tb.propertyList.get(i).getTypeOfData()
									.equals(TypeOfData.INT)) {
						type2 = TypeOfData.FLOAT;
					} else {
						if (tb.propertyList.get(i).getTypeOfData()
								.equals(TypeOfData.BOOLEAN))
							type2 = TypeOfData.BOOLEAN;
						else
							type2 = TypeOfData.CHAR;
					}
					if (type1.equals(type2) || en.getValue().equals("null"))
						_row.addEntry(en);
					else {
						// throw exception
						return -1;

					}
				}
			} else {
				_row = new DataRow(tb.propertyList.size());

				for (int i = 0; i < _row.getSize(); i++) {
					_row.getEntry(i).setName(tb.propertyList.get(i).getName());
					_row.getEntry(i).setOriginName(
							tb.propertyList.get(i).getOriginName());

				}

				for (int i = 0; i < columnList.size(); i++) {
					int index = tb.getIndexOfColumn(tableName + "."
							+ columnList.get(i));
					if (index == -1) {
						// throw exception
						return -1;
					} else {
						_row.setEntry(index, item.entryList.get(i));

					}
				}
			}
			boolean res = Database.addNewDataRow(tableName, _row);
			if(res==true)
				count++;
			
		}

		// dua row vao table.
	//	boolean res = Database.addNewDataRow(tableName, _row);

	return count;

	}

}
